#include "Avalon/Network/TcpClientSocketChannel.hpp"
#include <boost/asio.hpp>
#include "Avalon/Network/SocketThreadPool.hpp"
#include "Avalon/Network/SocketType.hpp"

using namespace Avalon;
using namespace Avalon::IO;
using namespace Avalon::Network;
using namespace Avalon::Network::Detail;
using namespace boost;
using namespace boost::asio;
using namespace std;
using boost::asio::ip::tcp;

TcpClientSocketChannel::TcpClientSocketChannel(const IpAddress& address) {
  boost::shared_ptr<SocketType> socket(new SocketType(
    SocketThreadPool::GetInstance().GetService()));
  m_reader.reset(new TcpSocketReader(socket));
  m_writer.reset(new TcpSocketWriter(socket));
  m_connection.reset(new TcpSocketConnection(false, address, socket, m_reader,
    m_writer));
}

TcpClientSocketChannel::~TcpClientSocketChannel() {}

void TcpClientSocketChannel::SetNoDelay(bool noDelay) {
  tcp::no_delay noDelayOption(noDelay);
  m_connection->m_socket->m_socket.set_option(noDelayOption);
}

bool TcpClientSocketChannel::GetNoDelay() const {
  tcp::no_delay noDelayOption;
  m_connection->m_socket->m_socket.get_option(noDelayOption);
  return noDelayOption.value();
}

TcpSocketConnection& TcpClientSocketChannel::GetConnection() {
  return *m_connection;
}

TcpSocketReader& TcpClientSocketChannel::GetReader() {
  return *m_reader;
}

TcpSocketWriter& TcpClientSocketChannel::GetWriter() {
  return *m_writer;
}

TcpClientSocketChannel::TcpClientSocketChannel(
    const boost::shared_ptr<TcpSocketConnection>& connection,
    const boost::shared_ptr<TcpSocketReader>& reader,
    const boost::shared_ptr<TcpSocketWriter>& writer)
    : m_connection(connection),
      m_reader(reader),
      m_writer(writer) {}
